/**
 * 
 */
package com.delta.rafg.core;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.delta.rafg.coredata.AObjectHelper;




/**
 * @author RAFG Development Team (D9785692)
 *
 */
public class AObjectHelperImpl extends AObjectHelper{
    
    public AObjectHelperImpl(){
        m_dInvCount = 0;
    }
    
    private static final String NULL                  = "NULL";
    private static final String BYTES                 = "<Bytes></Bytes>";
    private static final String LEFT_ARROW            = "<";
    private static final String LEFT_ARROW_WITH_SLASH = "</";
    private static final String RIGHT_ARROW           = ">";

    private static double       m_dInvCount           = 0;
    

    public String toXML(Object p_request) {
        return toXML(p_request, null);
    }

    protected String toXML(Serializable p_request) {
        return toXML(p_request, null);
    }

    protected String toXML(Object p_request, Object p_strName) {
        StringBuffer strBfrRequest = new StringBuffer("\r\n");

        if ( m_dInvCount++ > 5000 ) {
            //System.out.println("Maxed out recursions " + m_dInvCount);//sop
            return strBfrRequest.append("\r\n toXML() - too many attributes - maxed out recursions " + m_dInvCount).toString();
        }

        try {
            if ( p_request == null && (p_strName != null && p_strName.toString().trim().length() > 0) ) {
                strBfrRequest.append(LEFT_ARROW).append((p_strName)).append(RIGHT_ARROW);
                strBfrRequest.append(NULL);
                strBfrRequest.append(LEFT_ARROW_WITH_SLASH).append((p_strName)).append(RIGHT_ARROW);
                return strBfrRequest.toString();
            }
            else if ( p_request == null )
                return "";

            if ( p_strName == null )
                p_strName = p_request.getClass().getSimpleName();

            strBfrRequest.append(LEFT_ARROW).append((p_strName));

            Method[] methods = null;
            methods = p_request.getClass().getMethods();

            if ( p_request.getClass().isPrimitive()
                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.String")
                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.Integer")
                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.Double")
                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.Boolean") ) {
                strBfrRequest.append(p_request.toString());
            }
            else if ( p_request instanceof List<?> /*
                                                    * p_request.getClass().getName ( ).equals("java.util.ArrayList" )
                                                    */) {
                List<?> lstObj = (List<?>) p_request;

                if ( lstObj.size() > 0 )
                    strBfrRequest = new StringBuffer("\r\n");

                for ( int i = 0; i < lstObj.size(); i++ ) {
                    Object objValue = lstObj.get(i);
                    strBfrRequest.append(toXML(objValue, p_strName + "_" + i));
                }

                if ( lstObj.size() == 0 ) {
                    strBfrRequest.append(RIGHT_ARROW).append(NULL);
                    return sanityCheck(strBfrRequest, p_strName);
                }
                else {
                    return strBfrRequest.toString();
                }
            }
            else if ( p_request instanceof Map<?, ?> /*
                                                      * p_request.getClass().getName ( ).equals("java.util.HashMap" )
                                                      */) {
                strBfrRequest.append(RIGHT_ARROW);
                Map<?, ?> mapObj = (Map<?, ?>) p_request;
                Iterator<?> keys = mapObj.keySet().iterator();
                while ( keys.hasNext() ) {
                    Object key = keys.next();
                    strBfrRequest.append(toXML(mapObj.get(key), (key) + RIGHT_ARROW));
                }
            }
            else {
                try {
                    String objName = null;
                    for ( int i = 0; i < methods.length; i++ ) {
                        
                        if ( methods[i] == null || !(methods[i].getDeclaringClass().getName().startsWith("com.delta")) )
                            continue;
                        
                        if ( (methods[i].getName().startsWith("get") || methods[i].getName().startsWith("is")) ) {

                            objName = null;
                            if ( methods[i].getName().startsWith("get") )
                                objName = methods[i].getName().substring(3);

                            if ( methods[i].getName().startsWith("is") )
                                objName = methods[i].getName().substring(2);

                            if ( methods[i].getParameterTypes().length <= 0 ) {
                                try {
                                    Object resp = methods[i].invoke(p_request, (Object[]) null);

                                    if ( resp != null
                                            && resp.getClass() != null
                                            && resp.getClass().getName() != null
                                            && (resp.getClass().isPrimitive()
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.String")
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.Integer")
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.Double") || resp
                                                    .getClass().getName().equalsIgnoreCase("java.lang.Boolean")) ) {
                                        strBfrRequest.append(" ");
                                        strBfrRequest.append(objName);
                                        strBfrRequest.append("=");
                                        strBfrRequest.append("'");
                                        if (objName !=null && objName.toLowerCase().indexOf("password") > -1 )
                                            strBfrRequest.append("********");
                                        else
                                            strBfrRequest.append(resp);
                                        strBfrRequest.append("'");
                                    }
                                }
                                catch ( Exception ee ) {
                                    //ee.printStackTrace();
                                }
                            }
                        }
                    }

                    if ( (p_request.getClass() != null && p_request.getClass().getName() != null)
                            && !(p_request.getClass().isPrimitive()
                                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.String")
                                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.Integer")
                                    || p_request.getClass().getName().equalsIgnoreCase("java.lang.Double") || p_request
                                    .getClass().getName().equalsIgnoreCase("java.lang.Boolean")) )
                        strBfrRequest.append(RIGHT_ARROW);

                    for ( int i = 0; i < methods.length; i++ ) {

                        if ( methods[i] == null || !(methods[i].getDeclaringClass().getName().startsWith("com.delta")) )
                            continue;

                        if ( methods[i].getName().startsWith("get")
                                && !methods[i].getName().startsWith("getType")
                                && !methods[i].getName().startsWith("getSerializer")
                                && !methods[i].getName().startsWith("getDeSerializer")
                                && !methods[i].getName().startsWith("getInstance")
                                && !methods[i].getName().startsWith("getClass")
                                && !methods[i].getName().startsWith("getAll")
                                && !methods[i].getName().startsWith("getParam")
                                && !methods[i].getName().startsWith("getException")
                                && !methods[i].getName().startsWith("getColumn")
                                && !methods[i].getName().startsWith("getField")
                                && !methods[i].getName().startsWith("getRecord")
                                && !methods[i].getName().endsWith("RecordSet")
                                && !methods[i].getName().startsWith("getTable")
                                && !methods[i].getName().startsWith("getSelectedTable")
                                && !methods[i].getName().startsWith("getSyncData") ) {

                            objName = methods[i].getName().substring(3);
                            if ( methods[i].getParameterTypes().length <= 0 ) {
                                try {
                                    Object resp = methods[i].invoke(p_request);

                                    if ( resp != null
                                            && resp.getClass() != null
                                            && !(resp.getClass().isPrimitive()
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.String")
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.Integer")
                                                    || resp.getClass().getName().equalsIgnoreCase("java.lang.Double") || resp
                                                    .getClass().getName().equalsIgnoreCase("java.lang.Boolean")) ) {
                                        strBfrRequest.append(toXML(resp, objName));
                                    }
                                }
                                catch ( Exception ee ) {
                                    //ee.printStackTrace();
                                }
                            }
                        }
                    }
                }
                catch ( Exception eee ) {
                    //eee.printStackTrace();
                }
            }

        }
        catch ( Exception e ) {
            //e.printStackTrace();
        }
        return sanityCheck(strBfrRequest, p_strName);
    }

    private static String sanityCheck(StringBuffer strBuff, Object p_strName) {

        if(!strBuff.toString().endsWith(RIGHT_ARROW))
        	strBuff.append(RIGHT_ARROW);
        
    	strBuff.append(LEFT_ARROW_WITH_SLASH).append((p_strName));

        if ( p_strName != null && (!(p_strName.toString().endsWith(RIGHT_ARROW))) )
            strBuff.append(RIGHT_ARROW);

        return strBuff.toString().replaceAll(BYTES, "").replaceAll(">>", RIGHT_ARROW).replaceAll("<<", LEFT_ARROW);
    }

    @Override
    public AObjectHelper getInstance() {
        return new AObjectHelperImpl();
    }

	@Override
	public void setHttpData(Object rafgRequest, Object request) {
	}

}
